﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Script.Serialization;
using System.Web.Mvc;
using giaoxuhaison.Common;

namespace giaoxuhaison.Common
{
    public class BuildGridDataHelper<T> : IBuildGridDataHelper<T> where T:class 
    {
        private IPageCalculator _pageCalculator;
        private ISortBuilder _sortBuilder;
        private IEntityHelper _entityHelper;
        private IFilterBuilder _filterBuilder;

        public BuildGridDataHelper(IPageCalculator pageCalculator, IEntityHelper entityHelper,
            ISortBuilder sortBuilder, IFilterBuilder filterBuilder)
        {
            _pageCalculator = pageCalculator;
            _entityHelper = entityHelper;
            _sortBuilder = sortBuilder;
            _filterBuilder = filterBuilder;
        }

        public string BuildDataForGrid(List<T> sources, Func<T, string[]> generateCellValues,
            string sortName, string sortOrder, int rowsPerPage, int rowId, int page,
            string searchField, string searchOper, string searchString)
        {
            var sortedSource = new List<T>();

            if (searchField != null && searchField != string.Empty && searchOper != null && searchOper != string.Empty)
            {
                var filter = _filterBuilder.CreateExpression<T>(searchField, searchString, searchOper);
                if (filter != null)
                {
                    sources = sources.Where(filter).ToList();
                    sortedSource = _sortBuilder.Sort(sources, sortName, sortOrder, rowsPerPage);
                }
            }
            else
            {
                sortedSource = _sortBuilder.Sort(sources, sortName, sortOrder, rowsPerPage);
            }

            //Dungnv : 05/04/2013
            //var numberOfRecords = sortedSource.Count;
            var numberOfRecords=0;
            if (sortedSource != null)
            {
                numberOfRecords = sortedSource.Count;
            }
            //End Dungnv 

            var totalPages = (int)Math.Ceiling((numberOfRecords * 1.0) / rowsPerPage);

            var currentPage = (page > totalPages ? totalPages : page);
            if (rowId > 0)
            {
                var newIndex = sortedSource.FindIndex(x => _entityHelper.GetIdValue(x) == rowId);
                currentPage = (int)Math.Ceiling((newIndex * 1.0) / rowsPerPage);
            }

            var startIndex = (currentPage - 1) * rowsPerPage;

            //Dungnv 
            //sortedSource = sortedSource.Skip(startIndex).Take(rowsPerPage).ToList();
           
            //// Create data as format of grid
            //var _filter = sortedSource.Select(x => new
            //{
            //    id = _entityHelper.GetIdValue(x),
            //    cell = generateCellValues(x)
            //}).ToList();

            ////Create json data
            //var jsonData = new
            //{
            //    total = totalPages,
            //    page = currentPage,
            //    records = numberOfRecords,
            //    rows = _filter
            //};

            //var java = new JavaScriptSerializer();
            //java.MaxJsonLength = Int32.MaxValue;
            //return java.Serialize(jsonData);

         
            //Chinh sua lai trong truong hop khong co du lieu thi Grid tra ve null
            if (sortedSource != null)
            {
                sortedSource = sortedSource.Skip(startIndex).Take(rowsPerPage).ToList();
                // Create data as format of grid
                var _filter = sortedSource.Select(x => new
                {
                    id = _entityHelper.GetIdValue(x),
                    cell = generateCellValues(x)
                }).ToList();

                //Create json data
                var jsonData = new
                {
                    total = totalPages,
                    page = currentPage,
                    records = numberOfRecords,
                    rows = _filter
                };

                var java = new JavaScriptSerializer();
                java.MaxJsonLength = Int32.MaxValue;
                return java.Serialize(jsonData);
            }

            else
            {
                var jsonData =new
              {
                  total = 0,
                  page = 0,
                  records = 0,
                  rows = 0
              };

                var java = new JavaScriptSerializer();
                java.MaxJsonLength = Int32.MaxValue;
                return java.Serialize(jsonData);
            }
            //End Dungnv 

            
        }

        public string BuildDataForLazyGrid(List<T> sources, Func<T, string[]> generateCellValues, GridModel gridInfo)
        {
            // Create data as format of grid
            var _filter = sources.Select(x => new
            {
                id = _entityHelper.GetIdValue(x),
                cell = generateCellValues(x)
            }).ToList();

            //Create json data
            var jsonData = new
            {
                total = gridInfo.TotalPages,
                page = gridInfo.CurrentPage,
                records = gridInfo.TotalRecords,
                rows = _filter
            };

            var java = new JavaScriptSerializer();
            java.MaxJsonLength = Int32.MaxValue;
            return java.Serialize(jsonData);
        }

        public string BuildDataForPerformanceGrid(List<T> sources, Func<T, string[]> generateCellValues,
            string sortName, string sortOrder, int rowsPerPage, int rowId, int page,
            string searchField, string searchOper, string searchString, JsonResult totalValues)
        {
            var sortedSource = new List<T>();

            if (searchField != null && searchField != string.Empty && searchOper != null && searchOper != string.Empty)
            {
                var filter = _filterBuilder.CreateExpression<T>(searchField, searchString, searchOper);
                if (filter != null)
                {
                    sources = sources.Where(filter).ToList();
                    sortedSource = _sortBuilder.Sort(sources, sortName, sortOrder, rowsPerPage);
                }
            }
            else
            {
                sortedSource = _sortBuilder.Sort(sources, sortName, sortOrder, rowsPerPage);
            }

            var numberOfRecords = sortedSource.Count;
            var totalPages = (int)Math.Ceiling((numberOfRecords * 1.0) / rowsPerPage);

            var currentPage = (page > totalPages ? totalPages : page);
            if (rowId > 0)
            {
                var newIndex = sortedSource.FindIndex(x => _entityHelper.GetIdValue(x) == rowId);
                currentPage = (int)Math.Ceiling((newIndex * 1.0) / rowsPerPage);
            }

            var startIndex = (currentPage - 1) * rowsPerPage;

            sortedSource = sortedSource.Skip(startIndex).Take(rowsPerPage).ToList();

            // Create data as format of grid
            var _filter = sortedSource.Select(x => new
            {
                id = _entityHelper.GetIdValue(x),
                cell = generateCellValues(x)
            }).ToList();

            //var totalValue = "";

            //Create json data
            var jsonData = new
            {
                total = totalPages,
                page = currentPage,
                records = numberOfRecords,
                rows = _filter,
                totalValue = totalValues
            };

            var java = new JavaScriptSerializer();
            java.MaxJsonLength = Int32.MaxValue;
            return java.Serialize(jsonData);
        }

        public string BuildDataForInitiationGrid(List<T> sources, Func<T, string[]> generateCellValues,
            string sortName, string sortOrder, int rowsPerPage, int rowId, int page,
            string searchField, string searchOper, string searchString, JsonResult totalValues)
        {
            var sortedSource = new List<T>();

            if (searchField != null && searchField != string.Empty && searchOper != null && searchOper != string.Empty)
            {
                var filter = _filterBuilder.CreateExpression<T>(searchField, searchString, searchOper);
                if (filter != null)
                {
                    sources = sources.Where(filter).ToList();
                    sortedSource = _sortBuilder.Sort(sources, sortName, sortOrder, rowsPerPage);
                }
            }
            else
            {
                sortedSource = _sortBuilder.Sort(sources, sortName, sortOrder, rowsPerPage);
            }

            var numberOfRecords = sortedSource.Count;
            var totalPages = (int)Math.Ceiling((numberOfRecords * 1.0) / rowsPerPage);

            var currentPage = (page > totalPages ? totalPages : page);
            if (rowId > 0)
            {
                var newIndex = sortedSource.FindIndex(x => _entityHelper.GetIdValue(x) == rowId);
                currentPage = (int)Math.Ceiling((newIndex * 1.0) / rowsPerPage);
            }

            var startIndex = (currentPage - 1) * rowsPerPage;

            sortedSource = sortedSource.Skip(startIndex).Take(rowsPerPage).ToList();

            // Create data as format of grid
            var _filter = sortedSource.Select(x => new
            {
                id = _entityHelper.GetIdValue(x),
                cell = generateCellValues(x)
            }).ToList();

            //var totalValue = "";

            //Create json data
            var jsonData = new
            {
                total = totalPages,
                page = currentPage,
                records = numberOfRecords,
                rows = _filter,
                totalValue = totalValues
            };

            var java = new JavaScriptSerializer();
            java.MaxJsonLength = Int32.MaxValue;
            return java.Serialize(jsonData);
        }
    }
}